package com.aura.springbook.common.interceptor;

import com.aura.springbook.common.annotation.AdminRequired;
import com.aura.springbook.common.util.ResponseUtil;
import com.aura.springbook.common.exception.ResultCode;
import com.aura.springbook.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * 管理员权限检查拦截器
 * <p>
 * 负责拦截带有 @AdminRequired 注解的接口请求，进行权限验证
 * 确保只有管理员用户才能访问受保护的接口
 * <p>
 * 权限检查流程：
 * 1. 检查请求是否带有 @AdminRequired 注解
 * 2. 验证用户是否已登录（通过Session）
 * 3. 验证用户是否为管理员角色
 * <p>
 * 拦截失败时会返回相应的错误码：
 * - NOT_LOGIN: 用户未登录
 * - NO_AUTH: 权限不足
 */
@Component
public class AdminPermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    /**
     * 请求预处理
     * <p>
     * 在请求到达控制器方法之前进行权限检查
     *
     * @param request  HTTP请求对象
     * @param response HTTP响应对象
     * @param handler  处理器对象
     * @return true表示放行，false表示拦截
     * @throws Exception 处理异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 只处理方法级别的请求
        if (!(handler instanceof HandlerMethod handlerMethod)) {
            return true;
        }

        // 检查是否有 @AdminRequired 注解
        AdminRequired adminRequired = handlerMethod.getMethodAnnotation(AdminRequired.class);
        if (adminRequired == null) {
            adminRequired = handlerMethod.getBeanType().getAnnotation(AdminRequired.class);
        }

        // 如果没有注解，直接放行
        if (adminRequired == null) {
            return true;
        }

        // 检查用户权限
        HttpSession session = request.getSession(false);
        if (session == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            writeResponse(response, ResponseUtil.fail(ResultCode.NOT_LOGIN));
            return false;
        }

        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            writeResponse(response, ResponseUtil.fail(ResultCode.NOT_LOGIN));
            return false;
        }

        // 检查用户是否为管理员
        if (!userService.getUserById(userId).isAdmin()) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            writeResponse(response, ResponseUtil.fail(ResultCode.NO_AUTH, "权限不足，只有管理员才能执行此操作"));
            return false;
        }

        return true;
    }

    /**
     * 写入响应内容
     * <p>
     * 将响应对象转换为JSON格式并写入响应流
     *
     * @param response HTTP响应对象
     * @param result   响应结果对象
     * @throws IOException IO异常
     */
    private void writeResponse(HttpServletResponse response, Object result) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        try (PrintWriter writer = response.getWriter()) {
            writer.write(result.toString());
            writer.flush();
        }
    }
}